﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.Client;

namespace AppForAnonWithPublicDomainWeb.Pages
{
	public partial class DemoAppPart : System.Web.UI.Page
	{

		#region Poperties and fields

		private const string TargetPrincipalName = "00000003-0000-0ff1-ce00-000000000000";

		private bool EnsureInternalUrls
		{
			get
			{
				return Request["EnsureInternalUrls"] == "true";
			}
		}

		private string SPHostUrl
		{
			get
			{
				return Request["SPHostUrl"];
			}
		}

		private string SPAppWebUrl
		{
			get
			{
				return Request["SPAppWebUrl"];
			}
		}

		private string _internalSPHostUrl;
		private string InternalSPHostUrl
		{
			get
			{
				if (string.IsNullOrEmpty(_internalSPHostUrl))
				{
					if (EnsureInternalUrls)
					{
						_internalSPHostUrl = ExtractOriginalUrl(new Uri(SPHostUrl), true);
					}
					else
					{
						_internalSPHostUrl = SPHostUrl;
					}
				}
				return _internalSPHostUrl;
			}
		}


		private string _internalSPAppWebUrl;
		private string InternalSPAppWebUrl
		{
			get
			{
				if (string.IsNullOrEmpty(_internalSPAppWebUrl))
				{
					if (EnsureInternalUrls)
					{

						var lastIndex = SPAppWebUrl.LastIndexOf('/');
						var appWebRelativeUrl = SPAppWebUrl.Substring(lastIndex);
						_internalSPAppWebUrl = ExtractOriginalUrl(new Uri(InternalSPHostUrl + appWebRelativeUrl), false);
					}
					else
					{
						_internalSPAppWebUrl = SPAppWebUrl;
					}
				}
				return _internalSPAppWebUrl;
			}
		}

		#endregion

		protected void Page_Load(object sender, EventArgs e)
		{
			try
			{
				BindHostWebParams();
			}
			catch (Exception ex)
			{
				lblHostError.Text = ex.ToString();
			}

			try
			{
				BindAppWebParams();
			}
			catch (Exception ex)
			{
				lblAppError.Text = ex.ToString();
			}
		}

		private void BindHostWebParams()
		{
			lblSPHostUrl.Text = SPHostUrl;
			pnlSPHostUrlInternal.Visible = EnsureInternalUrls;
			lblSPHostUrlInternal.Text = InternalSPHostUrl;

			var uri = new Uri(InternalSPHostUrl);
			var token = TokenHelper.GetAppOnlyAccessToken(TargetPrincipalName, uri.Authority, TokenHelper.GetRealmFromTargetUrl(uri));
			using (ClientContext ctx = TokenHelper.GetClientContextWithAccessToken(InternalSPHostUrl, token.AccessToken))
			{
				var web = ctx.Web;
				ctx.Load(web);
				ctx.ExecuteQuery();
				lblSPHostTitle.Text = web.Title;
			}
		}

		private void BindAppWebParams()
		{
			lblSPAppWebUrl.Text = SPAppWebUrl;
			pnlSPAppWebUrlInternal.Visible = EnsureInternalUrls;
			lblSPAppWebUrlInternal.Text = InternalSPAppWebUrl;

			var uri = new Uri(InternalSPAppWebUrl);
			var token = TokenHelper.GetAppOnlyAccessToken(TargetPrincipalName, uri.Authority, TokenHelper.GetRealmFromTargetUrl(uri));

			using (ClientContext ctx = TokenHelper.GetClientContextWithAccessToken(InternalSPAppWebUrl, token.AccessToken))
			{
				var web = ctx.Web;
				ctx.Load(web);
				ctx.ExecuteQuery();
				lblSPAppWebTitle.Text = web.Title;
			}
		}

		#region Helpers


		private static string ExtractOriginalUrl(Uri urlFromRequest, bool isHostWeb)
		{
			var url = urlFromRequest + (isHostWeb ? "/_layouts/15/Authenticate.aspx" : "");
			HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
			EmulateBrowserWebRequest(webRequest);
			HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();

			var originalHostUrl = HttpUtility.ParseQueryString(response.ResponseUri.Query)["wreply"];
			if (string.IsNullOrEmpty(originalHostUrl))
			{
				return string.Empty;
			}
			var index = originalHostUrl.IndexOf("_form", StringComparison.InvariantCultureIgnoreCase);
			if (index > 0)
			{
				originalHostUrl = originalHostUrl.Substring(0, index - 1);
			}

			var relativePathFromRequest = urlFromRequest.GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped).TrimEnd('/');
			var originalUrlServerPath = new Uri(originalHostUrl).GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped);
			return string.Format("{0}{1}", originalUrlServerPath, relativePathFromRequest);
		}

		private static void EmulateBrowserWebRequest(HttpWebRequest request)
		{
			request.Method = "HEAD";
			request.AllowAutoRedirect = true;

			request.Accept = "text/html, application/xhtml+xml, */*";
			request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)";

			request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip");
			request.AutomaticDecompression = DecompressionMethods.GZip;
			request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US");

			request.Headers.Add(HttpRequestHeader.CacheControl, "max-age=0");
		}

		#endregion
	}
}